program dvip_sar;

type link = ^elem;
	elem = record
		val: integer;   	//reiksme
		prv: link;	//link i praeita elementa
		nxt: link;	//link i kita elementa
	end;

type list = ^q;
	q = record
		head: link;		//saraso head ir tail apibrezia sarasa.
		tail: link;
	end;
	
{----------------------------------------------------------------------------------------------------------------------------------------}
{----------------------------------------------------------------------------------------------------------------------------------------}

procedure init(var m:list);
begin
	new(m);			//padaro kad rodykle turetu i ka rodyti 
	m^.head := nil;
	m^.tail := nil;
end;

function empty(m:list): boolean;
begin
	if (m^.head = nil)
		then	empty := TRUE
		else	empty := FALSE;
end;

function size(m:list):integer;	//suskaiciuoja kiek viso yra elementu sarase.
var i: integer;
	tmp: link;
begin
	tmp := m^.head;
	if empty(m) then i := 0	
	else 
		begin
			i := 1;				//kadangi neempty tai maziausiai gali tureti viena
			while tmp^.nxt <> nil do	//ciklas slenkasi iki galo.. kas kart i padidindamas vienetu
				begin
					i := i+1;
					tmp := tmp^.nxt;
				end;
		end;
	size := i;
end;

procedure insert(var m:list; x:integer; nr:integer);	//iterpta reiksme "x" bus su numeriu "nr"
var tmp,l_tmp: link;		//tmp naudosim naujam elementui kurti, o l_tmp for cikle tiesiog kad daeitu ir rastu reikiama vieta sarase..
	i:integer;
begin
	if (nr > (size(m)+1)) OR (nr < 1) then exit;	//reikia iseiti is funkcijos jei ivestas negalimas skaicius (per mazas arba per didelis)
	
	new(tmp);
	tmp^.val := x;
	tmp^.nxt := nil;
	tmp^.prv := nil;
							//iterpimas suskirstytas i 4 atvejus:
	if empty(m) then							//1.kai terpiama i tuscia sarasa
		begin
			m^.head := tmp;
			m^.tail := tmp;
		end
	else
		begin
			if nr = 1 then						//2.kai terpiama i pradzia
				begin
					tmp^.nxt := m^.head;
					m^.head^.prv := tmp;
					m^.head := tmp;
				end
			else if nr > size(m) then			//3.kai terpiama i pabaiga
				begin
					tmp^.prv := m^.tail;
					m^.tail^.nxt := tmp;
					m^.tail := tmp;
				end
			else								//4.kai terpiama kazkur i viduri
				begin
					l_tmp := m^.head;
					for i:= 1 to (nr)-1 do 	l_tmp := l_tmp^.nxt;
					l_tmp^.prv^.nxt := tmp;
					tmp^.prv := l_tmp^.prv;
					l_tmp^.prv := tmp;
					tmp^.nxt := l_tmp;
				end
		end;
end;

procedure del(var m:list;nr :integer);
var tmp: link;
	i:integer;
begin
	if empty(m) then exit;
	if (nr > size(m)) OR (nr < 1) then exit;

						//trynimo operacijai iskyreme 4 atvejus:
	if size(m)=1 then				//1.paskutinio elemento atvejis (jei sarase liko vienintelis elementas)
		begin
			dispose(m^.head);
			m^.tail:=nil;
		end
		
	else
	if nr = size(m) then			//2.galinio elemento atvejis
		begin
			m^.tail := m^.tail^.prv;
			dispose(m^.tail^.nxt);
			m^.tail^.nxt := nil;
		end
		
	else
	if nr =1 then					//3.pirmo elemento atvejis
		begin
			m^.head := m^.head^.nxt;
			dispose(m^.head^.prv);
			m^.head^.prv := nil;
		end
		
	else							//4.like atvejai, (vidiniai elementai)
		begin
		tmp := m^.head;
			for i:= 1 to (nr-1) do 	tmp := tmp^.nxt;
			tmp^.prv^.nxt := tmp^.nxt;
			tmp^.nxt^.prv := tmp^.prv;
			dispose(tmp);
		end
end;


function peek(m:list; nr:integer):integer;	//paziureti elemento su "nr" reiksme
var i: integer;
tmp:link;
begin
	if (nr > size(m)) OR (nr < 1) then exit;
	if nr =1 then peek := m^.head^.val				//jei ziurimas pirmas elementas
	else if nr = size(m) then peek := m^.tail^.val	//jei ziurimas paskutinis elementas
	else											//jei like avejai
		begin
			tmp := m^.head;
			for i:= 1 to (nr-1) do 	tmp := tmp^.nxt;
			peek := tmp^.val;
		end;
end;

procedure delete_all(var m:list);
var tmp: link;
begin
	if empty(m) then exit;
	while m^.head <> m^.tail do
		begin
			m^.tail := m^.tail^.prv;
			dispose(m^.tail^.nxt);
		end;
	dispose(m^.head);
end;

procedure print_all(m:list);
var tmp: link;
begin
	tmp := m^.head;
	write('Sarasas:  ');
	while tmp <> nil do
		begin
			write(tmp^.val,' ');
			tmp := tmp^.nxt;
		end;
		writeln;
		writeln;
end;

{----------------------------------------------------------------------------------------------------------------------------------------}
{----------------------------------------------------------------------------------------------------------------------------------------}
var i,a,skaicius,kur: integer;
	m : list;
{----------------------------------------------------------------------------------------------------------------------------------------}
{----------------------------------------------------------------------------------------------------------------------------------------}
begin
	init(m);
	for i := 1 to 10 do		//automatiskai iterps 10 elementu
		begin
			skaicius := random(50);
			kur := random(i-1)+1;
			writeln(' I saraso vieta nr: ',kur,'');
			writeln('iterptas skaicius: ',skaicius,'');
			insert(m,skaicius,kur);
			writeln('Dabar saraso dydis yra: ',size(m));
			print_all(m);
		end;				//automatines prezentacijos pabaiga :)
	writeln;
	writeln;
	writeln;
	
	
	while true do			//darom amzina cikla (isejimui is jo numateme salygas jo viduje..)
	begin
		writeln(' 1-insert ');
		writeln(' 2-del ');
		writeln(' 3-peek ');
		writeln(' 4-size ');
		writeln(' 5-print_all ');
		writeln(' 6-delete_all');
		writeln(' 7-ar tuscias');
		writeln('noredami iseiti spauskit bet kuri kita skaiciu');
		readln(a);
		
		case a of
			1:	begin
					read(skaicius);
					read(kur);
					if ( (kur>0) AND (kur<=(size(m)+1)) ) then insert(m,skaicius,kur);
				end;
				
			2:	begin
					read(kur);
					if ( (kur>0) AND (kur<=size(m)) ) then del(m,kur);
				end;
				
			3:	begin
					read(kur);
					if ( (kur>0) AND (kur<=size(m)) ) then writeln('Reiksme yra: ',peek(m,kur));
				end;
			4:	writeln('Saraso elementu kiekis: ',size(m));
			5:	print_all(m);
			6:	delete_all(m);
			7:	if empty(m) then writeln('sarasas tuscias')
							else writeln('sarasas nera tuscias');
			else
				delete_all(m);
				exit;
		end;
	end;
end.
